home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 051-075 / disk_068 / mg1b / tty / amiga / tty.c < prev    next >
C/C++ Source or Header  |  1992-05-06  |  10KB  |  505 lines

  1. /*
  2.  * Name:    MicroEMACS
  3.  *        Amiga console device virtual terminal display
  4.  * Version:    GNU v30
  5.  * Last Edit:    19-Jan-87 ...!ihnp4!seismo!ut-sally!ut-ngp!mic
  6.  * Created:    19-Apr-86 ...!ihnp4!seismo!ut-sally!ut-ngp!mic
  7.  *
  8.  * Drives the Amiga console device display.  The code
  9.  * is basically like the termcap driver in that it
  10.  * uses the console device scrolling region.  It also
  11.  * has some hacks to manage the console device colors.
  12.  */
  13.  
  14. #include <exec/types.h>
  15. #include <exec/nodes.h>
  16. #include <exec/lists.h>
  17. #include <exec/tasks.h>
  18. #include <exec/ports.h>
  19. #include <exec/io.h>
  20. #include <devices/console.h>
  21. #include <libraries/dos.h>
  22. #include <graphics/clip.h>
  23. #include <graphics/view.h>
  24. #include <graphics/rastport.h>
  25. #include <graphics/layers.h>
  26. #include <graphics/text.h>
  27. #include <graphics/gfxbase.h>
  28. #ifndef    MANX
  29. #include <intuition/intuitionbase.h>
  30. #endif
  31. #include <intuition/intuition.h>
  32.  
  33. #undef    TRUE
  34. #undef    FALSE
  35. #include    "def.h"
  36.  
  37. #define    BEL    0x07            /* BEL character.        */
  38. #define    ESC    0x1B            /* ESC character.        */
  39. #define    LF    0x0A            /* Linefeed character        */
  40. #define    CSI    0x9B            /* Command Sequence Introducer    */
  41.  
  42. extern    int    ttrow;
  43. extern    int    ttcol;
  44. extern    int    tttop;
  45. extern    int    ttbot;
  46. extern    int    tthue;
  47.  
  48. int    tceeol    =    3;        /* Costs, ANSI display.        */
  49. int    tcinsl    =     17;
  50. int    tcdell    =    16;
  51.  
  52.  
  53. #ifdef    CHANGE_COLOR
  54. short    mode_rendition = MODE_RENDITION,    /* set standard colors */
  55.     text_rendition = TEXT_RENDITION,
  56.     text_fg = TEXT_FG + 30,
  57.     text_bg = TEXT_BG + 40,
  58.     mode_fg = MODE_FG + 30,
  59.     mode_bg = MODE_BG + 40;
  60. #else                /* colors are hard-coded        */
  61. #define mode_rendition MODE_RENDITION
  62. #define    text_rendition TEXT_RENDITION
  63. #define text_fg (TEXT_FG + 30)
  64. #define text_bg (TEXT_BG + 40)
  65. #define mode_fg (MODE_FG + 30)
  66. #define mode_bg (MODE_BG + 40)
  67. #endif
  68.  
  69. #ifdef    LATTICE
  70. VOID    asciiparm(int) ;
  71. #else
  72. VOID    asciiparm() ;
  73. #endif
  74. VOID    ttnowindow() ;
  75. VOID    ttwindow() ;
  76.  
  77. /*
  78.  * Initialize the terminal when the editor
  79.  * Initialize the virtual terminal.
  80.  * Set the console device's top edge below
  81.  * the front-to-back gadgets, to avoid
  82.  * garbage when scrolling.
  83.  */
  84. VOID
  85. ttinit()
  86. {
  87.     ttputc(CSI);
  88.     asciiparm(TOP_OFFSET);
  89.     ttputc('y');
  90. }
  91.  
  92. /*
  93.  * Clean up the terminal, in anticipation of
  94.  * a return to the command interpreter. This
  95.  * is a no-op on the Amiga, since the window
  96.  * is deleted anyway.
  97.  */
  98. VOID
  99. tttidy()
  100. {
  101. }
  102.  
  103. /*
  104.  * Move the cursor to the specified
  105.  * origin 0 row and column position. Try to
  106.  * optimize out extra moves; redisplay may
  107.  * have left the cursor in the right
  108.  * location last time!
  109.  */
  110. VOID
  111. ttmove(row, col)
  112. {
  113.     if (ttrow!=row || ttcol!=col) {
  114.         ttputc(ESC);
  115.         ttputc('[');
  116.         asciiparm(row+1);
  117.         ttputc(';');
  118.         asciiparm(col+1);
  119.         ttputc('H');
  120.         ttrow = row;
  121.         ttcol = col;
  122.     }
  123. }
  124.  
  125. /*
  126.  * Erase to end of line.
  127.  */
  128. VOID
  129. tteeol()
  130. {
  131.     ttputc(ESC);
  132.     ttputc('[');
  133.     ttputc('K');
  134. }
  135.  
  136. /*
  137.  * Erase to end of page.
  138.  */
  139. VOID
  140. tteeop()
  141. {
  142.     ttputc(ESC);    /* reinforce current color values */
  143.     ttputc('[');
  144.     asciiparm((tthue == CTEXT) ? text_rendition : mode_rendition);
  145.     ttputc(';');
  146.     asciiparm(text_fg);
  147.     ttputc(';');
  148.     asciiparm(text_bg);
  149.     ttputc('m');
  150.  
  151.     ttputc(ESC);    /* clear to end of display */
  152.     ttputc('[');
  153.     ttputc('J');
  154. }
  155.  
  156. /*
  157.  * Make a noise.
  158.  */
  159. VOID
  160. ttbeep()
  161. {
  162.     ttputc(BEL);
  163.     ttflush();
  164. }
  165.  
  166. /*
  167.  * Convert a number to decimal
  168.  * ascii, and write it out. Used to
  169.  * deal with numeric arguments.
  170.  */
  171. VOID
  172. asciiparm(n)
  173. register int    n;
  174. {
  175.     if (n > 9)
  176.         asciiparm(n/10);
  177.     ttputc((n%10) + '0');
  178. }
  179.  
  180. /*
  181.  * Insert a block of blank lines onto the
  182.  * screen, using a scrolling region that starts at row
  183.  * "row" and extends down to row "bot".  Deal with the one
  184.  * line case, which is a little bit special, with special
  185.  * case code.
  186.  */
  187. VOID
  188. ttinsl(row, bot, nchunk)
  189. {
  190.     if (row == bot) {            /* Funny case.        */
  191.         if (nchunk != 1)
  192.             panic("ttinsl: nchunk != 1");
  193.         ttmove(row, 0);
  194.         tteeol();
  195.         return;
  196.     } 
  197.     ttmove(1+bot-nchunk, 0);
  198.     if (nchunk > 0) {
  199.         ttwindow(row, bot);
  200.         ttputc(CSI);
  201.           asciiparm(nchunk);
  202.         ttputc('T');        /* Scroll scrolling region down    */
  203.         ttnowindow();
  204.     }
  205. }
  206.  
  207. /*
  208.  * Delete a block of lines, with the uppermost
  209.  * line at row "row", in a screen slice that extends to
  210.  * row "bot". The "nchunk" is the number of lines that have
  211.  * to be deleted.  It's really easy with the console
  212.  * device scrolling region.
  213.  */
  214. VOID
  215. ttdell(row, bot, nchunk)
  216. {
  217.     if (row == bot) {        /* One line special case    */
  218.         ttmove(row, 0);
  219.         tteeol();
  220.         return;
  221.     }
  222.     if (nchunk > 0) {
  223.         ttwindow(row, bot);
  224.         ttputc(CSI);
  225.           asciiparm(nchunk);
  226.         ttputc('S');        /* Scroll scrolling region up    */
  227.         ttnowindow();
  228.     }
  229.     ttrow = HUGE;
  230.     ttcol = HUGE;
  231.     ttmove(bot-nchunk,0);
  232. }
  233.  
  234. /*
  235.  * This routine sets the scrolling window
  236.  * on the display to go from line "top" to line
  237.  * "bot" (origin 0, inclusive). The caller checks
  238.  * for the pathalogical 1 line scroll window that
  239.  * doesn't work right on all systems, and avoids it.
  240.  * The "ttrow" and "ttcol" variables are set to a
  241.  * crazy value to ensure that ttmove() actually does
  242.  * something.
  243.  */
  244.  
  245. extern    struct Window    *EmW;            /* The window MG uses */
  246.  
  247. VOID
  248. ttwindow(top,bot)
  249. {
  250.     if (tttop != top || ttbot != bot) {
  251.         ttputc(CSI);            /* Home cursor        */
  252.         ttputc('H');
  253.  
  254.         ttputc(CSI);            /* Set top offset    */
  255.         asciiparm(TOP_OFFSET + top * FontHeight(EmW));
  256.         ttputc('y');
  257.  
  258.         ttputc(CSI);
  259.         asciiparm(bot - top + 1);    /* Set page length    */
  260.         ttputc('t');
  261.  
  262.         ttrow = HUGE;            /* Force cursor reset    */
  263.         ttcol = HUGE;
  264.         tttop = top;            /* Save region state    */
  265.         ttbot = bot;
  266.     }
  267. }
  268.  
  269. /*
  270.  * Switch to full screen scrolling
  271.  */
  272. VOID
  273. ttnowindow()
  274. {
  275.     ttputc(CSI);            /* Home cursor            */
  276.     ttputc('H');
  277.  
  278.     ttputc(CSI);            /* Set top offset to normal    */
  279.     asciiparm(TOP_OFFSET);
  280.     ttputc('y');
  281.  
  282.     ttputc(CSI);            /* Set page length to nrow    */
  283.     asciiparm(nrow);
  284.     ttputc('t');
  285.  
  286.     ttrow = HUGE;            /* Make cursor unknown.        */
  287.     ttcol = HUGE;
  288.     tttop = HUGE;
  289.     ttbot = HUGE;
  290. }
  291.  
  292. #ifdef    CHANGE_COLOR
  293. /*
  294.  * Set the rendition of the mode line by
  295.  * selecting colors from the following:
  296.  *    0 -- plain text
  297.  *    1 -- bold-face
  298.  *    3 -- italic
  299.  *    4 -- underscore
  300.  *    7 -- inverse video
  301.  * Certain of these selections may be less than
  302.  * appealing :-)
  303.  */
  304.  
  305. ttmode(f, n, k)
  306. {
  307.     register int    s;
  308.     char        buf[2];
  309.  
  310.     if (f == FALSE) {
  311.         if ((s = ereply("Set mode line rendition (0-7): ",
  312.                 buf, sizeof(buf))) != TRUE)
  313.             return (s);
  314.         n = atoi(buf);
  315.     }
  316.     if (n < 0 || n > 7)
  317.         return (FALSE);
  318.  
  319.     mode_rendition = n;        /* store the color    */
  320.     sgarbf = TRUE;
  321.     return (TRUE);
  322. }
  323.  
  324. /*
  325.  * Set the rendition of the text area.
  326.  * Most of these selections will be
  327.  * less than appealing :-]
  328.  */
  329.  
  330. tttext(f, n, k)
  331. {
  332.     register int    s;
  333.     char        buf[2];
  334.  
  335.     if (f == FALSE) {
  336.         if ((s = ereply("Set text rendition (0-7): ",
  337.                 buf, sizeof(buf))) != TRUE)
  338.             return (s);
  339.         n = atoi(buf);
  340.     }
  341.     if (n < 0 || n > 7)
  342.         return (FALSE);
  343.  
  344.     text_rendition = n;        /* store the color    */
  345.     sgarbf = TRUE;
  346.     return (TRUE);
  347. }
  348.  
  349. /*
  350.  * Set foreground color for entire window
  351.  * to a value between 30 and 37, which
  352.  * corresponds to the arguments 0-7.
  353.  * This requires a total refresh, which
  354.  * sets up the screen.
  355.  */
  356.  
  357. textforeground(f, n, k)
  358. {
  359.     register int    s;
  360.     char        buf[2];
  361.  
  362.     if (f == FALSE) {
  363.         if ((s = ereply("Text foreground color (0-7): ",
  364.                 buf, sizeof(buf))) != TRUE)
  365.             return (s);
  366.         n = atoi(buf);
  367.     }
  368.     if (n < 0 || n > 7)
  369.         return (FALSE);
  370.  
  371.     text_fg = n + 30;
  372.     sgarbf = TRUE;
  373.     return (TRUE);
  374. }
  375.  
  376. /*
  377.  * Set background color for entire window
  378.  * to a value between 40 and 47 inclusive.
  379.  */
  380.  
  381. textbackground(f, n, k)
  382. {
  383.     register int    s;
  384.     char        buf[2];
  385.  
  386.     if (f == FALSE) {
  387.         if ((s = ereply("Text background color (0-7): ",
  388.                 buf, sizeof(buf))) != TRUE)
  389.             return (s);
  390.         n = atoi(buf);
  391.     }
  392.     if (n < 0 || n > 7)
  393.         return (FALSE);
  394.  
  395.     text_bg = n + 40;
  396.     sgarbf = TRUE;
  397.     return (TRUE);
  398. }
  399.  
  400. /*
  401.  * Set foreground color for entire the mode line
  402.  */
  403.  
  404. modeforeground(f, n, k)
  405. {
  406.     register int    s;
  407.     char        buf[2];
  408.  
  409.     if (f == FALSE) {
  410.         if ((s = ereply("Mode line foreground color (0-7): ",
  411.                 buf, sizeof(buf))) != TRUE)
  412.             return (s);
  413.         n = atoi(buf);
  414.     }
  415.     if (n < 0 || n > 7)
  416.         return (FALSE);
  417.  
  418.     mode_fg = n + 30;
  419.     sgarbf = TRUE;
  420.     return (TRUE);
  421. }
  422.  
  423. /*
  424.  * Set background color for the mode line
  425.  */
  426.  
  427. modebackground(f, n, k)
  428. {
  429.     register int    s;
  430.     char        buf[2];
  431.  
  432.     if (f == FALSE) {
  433.         if ((s = ereply("Mode line background color (0-7): ",
  434.                 buf, sizeof(buf))) != TRUE)
  435.             return (s);
  436.         n = atoi(buf);
  437.     }
  438.     if (n < 0 || n > 7)
  439.         return (FALSE);
  440.  
  441.     mode_bg = n + 40;
  442.     sgarbf = TRUE;
  443.     return (TRUE);
  444. }
  445. #endif
  446.  
  447. /*
  448.  * Set the current writing color to the
  449.  * specified color. Watch for color changes that are
  450.  * not going to do anything (the color is already right)
  451.  * and don't send anything to the display.
  452.  */
  453.  
  454. VOID
  455. ttcolor(color)
  456. register int    color;
  457. {
  458.     if (color != tthue) {
  459.         if (color == CTEXT) {        /* Normal video.    */
  460.             ttputc(ESC);        /* Reset to 0        */
  461.             ttputc('[');
  462.             ttputc('m');
  463.             ttputc(ESC);        /* Set text style    */
  464.             ttputc('[');
  465.             asciiparm(text_rendition);
  466.             ttputc(';');
  467.             asciiparm(text_fg);
  468.             ttputc(';');
  469.             asciiparm(text_bg);
  470.             ttputc('m');
  471.         } else if (color == CMODE) {    /* Standout mode    */
  472.             ttputc(ESC);        /* Reset to 0        */
  473.             ttputc('[');
  474.             ttputc('m');
  475.             ttputc(ESC);        /* Set standout mode    */
  476.             ttputc('[');
  477.             asciiparm(mode_rendition);
  478.             ttputc(';');
  479.             asciiparm(mode_fg);    /* Use mode line colors    */
  480.             ttputc(';');
  481.             asciiparm(mode_bg);
  482.             ttputc('m');
  483.         }
  484.         tthue = color;            /* Save the color.    */
  485.     }
  486. }
  487.  
  488. /*
  489.  * This routine is called by the
  490.  * "refresh the screen" command to try and resize
  491.  * the display. The new size, which must be deadstopped
  492.  * to not exceed the NROW and NCOL limits, is stored
  493.  * back into "nrow" and "ncol". Display can always deal
  494.  * with a screen NROW by NCOL. Look in "window.c" to
  495.  * see how the caller deals with a change.
  496.  * On the Amiga, we make the Intuition terminal driver
  497.  * do all the work.
  498.  */
  499.  
  500. VOID
  501. ttresize()
  502. {
  503.      setttysize();
  504. }
  505.